#!/usr/bin/python

## Version 1.0

import cStringIO
import Image, ImageEnhance
import cgi, time
import sys, traceback, base64
#import cgitb
import urllib2, socket
from threading import Thread
#cgitb.enable()

socket.setdefaulttimeout(10)

def printError(msg):
        print "Content-type: text/plain\n"
        print msg
        sys.exit(-1)

class OpenUrl(Thread):
	def __init__(self, url):
		Thread.__init__(self)
		self.url = url
		self.img = None
		self.attempts = 0;
	def run(self):
		self.attempts += 1
		try:
			self.img = urllib2.urlopen(self.url)
		except:
			self.secondTry()
	def secondTry(self):
		self.attempts += 1
		try:
			self.img = urllib2.urlopen(self.url)
		except:
			self.thirdTry()
	def thirdTry(self):
		self.attempts += 1
		try:
			self.img = urllib2.urlopen(self.url)
		except:
			foo = 1



def checkImageValues(form, i):
        if ("uc%s" % i) not in form:
                printError(("Image url not given in image%s" % i))
                sys.exit(-1)
        if ("h%s" % i) not in form:
                printError("Image height not given in image%s" % i)
                sys.exit(-1)
        if ("w%s" % i) not in form:
                printError("Image width not given in image "+i)
                sys.exit(-1)
        if ("o%s" % i) not in form:
                printError("Image opacity not given in image "+i)
                sys.exit(-1)
        if ("t%s" % i) not in form:
                printError("Image top not given in image "+i)
                sys.exit(-1)
        if ("l%s" % i) not in form:
                printError("Image left not given in image "+i)
                sys.exit(-1)
        if ("sx%s" % i) not in form:
                printError("Image sx not given in image "+i)
                sys.exit(-1)
        if ("sy%s" % i) not in form:
                printError("Image sy not given in image "+i)
                sys.exit(-1)


# result form structure
# imageHeight
# imageWidth
# numImages
#  - url
#  - height
#  - width
#  - opacity
#  - top
#  - left
#  - sx
#  - sy

# for debug
#print "Content-type: text/plain\n"

callback = "f"
# form operations
form = cgi.FieldStorage()
if "ih" not in form:
        printError("No height given");
if "iw" not in form:
        printError("No width given");
if "ni" not in form:
        printError("Number of images not given");
if "callback" in form:
	callback = form["callback"].value


imageHeight = int(form["ih"].value)
imageWidth = int(form["iw"].value)
numImages = int(form["ni"].value)

canvas = Image.new("RGBA", (imageWidth, imageHeight), (0, 0, 0, 0))

list = range(numImages)

threadlist = []
for i in list:
	urlc = form[("uc%s" % i)].value

	urlbId = form[("uid%s" % i)].value
	urlb = form[("urlb%s" % urlbId)].value

	
#	print "trying: http://%s%s" % (urlb, urlc)
	current = OpenUrl("http://%s%s" % (urlb, urlc))
	threadlist.append(current)
	current.start()

for i in list:
        checkImageValues(form, i);
	height = int(form[("h%s" % i)].value)
	width = int(form[("w%s" % i)].value)
	opacity = float(form[("o%s" % i)].value)
	top = int(form[("t%s" % i)].value)
	left = int(form[("l%s" % i)].value)
	sx = int(form[("sx%s" % i)].value)
	sy = int(form[("sy%s" % i)].value)
	
	t = time.time()
	try:
	
		# download image	
		threadlist[i].join()
		f = threadlist[i].img
		
#		print threadlist[i].url
		
		if f is None:
#			print "  dead, attempts = %s" % threadlist[i].attempts
#			print "  %s" % (time.time() - t)
#			print ""
			continue
#		print "  ok, attempts = %s" % threadlist[i].attempts

		tmp = cStringIO.StringIO(f.read())
		img = Image.open(tmp)

		# crop to size
		box = (sx, sy, width, height)
		img = img.crop(box)
		
		# set opacity
		if img.mode != 'RGBA':
			img = img.convert('RGBA')
		else:
			img = img.copy()
		alpha = img.split()[3]
		alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
		img.putalpha(alpha)

		# paste to canvas
		layer = Image.new('RGBA', canvas.size, (0,0,0,0))
		layer.paste(img, (left, top))
		canvas = Image.composite(layer, canvas, layer)
		#canvas.paste(img, (left, top), img)
#		print "  %s" % (time.time() - t)
#		print ""
	except:
		foo = 1
		#for debug
#		exc_type, exc_value, exc_traceback = sys.exc_info()
#		print "errors with "+url+"\n"
#		print "*** print_tb:"
#		traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
#		print "*** print_exception:"
#		traceback.print_exception(exc_type, exc_value, exc_traceback,
#                             limit=2, file=sys.stdout)

# returning image
f = cStringIO.StringIO()
canvas.save(f, "PNG")

#print "Content-Disposition: inline; filename=\"MapExport.png\""
#print "Content-type: image/png\n"
print "Content-type: text/plain\n"
f.seek(0)
data = base64.encodestring(f.read()).replace("\n", "")
f.close()
print "%s(\"%s\")" % (callback, data)

